import axios from 'axios'
import { ElLoading, ElMessage } from 'element-plus'
import { useBasicStore } from '@/store/basic'
import { userRefreshTokenCheck } from '@/api/user'

//使用axios.create()创建一个axios请求实例
const service = axios.create()
let loadingInstance: any = null //loading实例
let tempReqUrlSave = ''
let requests: any[] = [] // 错误接口队列
let isRefreshing = false

//请求前拦截
service.interceptors.request.use(
  (req: any) => {
    if (typeof req.data === 'string') {
      req.data = JSON.parse(req.data)
    }
    const { token, axiosPromiseArr, refreshToken }: any = storeToRefs(useBasicStore())
    //axiosPromiseArr收集请求地址,用于取消请求
    req.cancelToken = new axios.CancelToken((cancel) => {
      tempReqUrlSave = req.url
      axiosPromiseArr.value.push({
        url: req.url,
        cancel
      })
    })
    // @ts-ignore
    if (req.__isRefreshToken) {
      req.headers['Authorization'] = refreshToken.value
    } else {
      req.headers['Authorization'] = token.value
    }
    //如果req.method给get 请求参数设置为 ?name=xxx
    if ('get'.includes(req.method?.toLowerCase()) && !req.params) req.params = req.data

    //req loading
    // @ts-ignore
    if (req.reqLoading ?? true) {
      loadingInstance = ElLoading.service({
        lock: true,
        fullscreen: true,
        // spinner: 'CircleCheck',
        text: '数据载入中...',
        background: 'rgba(0, 0, 0, 0.1)'
      })
    }
    return req
  },
  (err) => {
    //发送请求失败
    Promise.reject(err)
  }
)
//请求后拦截
service.interceptors.response.use(
  (res: any) => {
    //取消请求
    useBasicStore().remotePromiseArrByReqUrl(tempReqUrlSave)
    if (loadingInstance) {
      loadingInstance && loadingInstance.close()
    }
    // 文件下载
    if (res.config?.responseType === 'blob') {
      return res
    }
    const { data, message } = res.data
    const { code, flag, content } = message
    // 省市区 特殊处理
    if (res.config?.baseURL === 'region') {
      if (flag === 'success') {
        return data
      }
      if (flag === 'error') {
        ElMessage.error({
          message: content,
          duration: 2 * 1000
        })
        return Promise.reject(content)
      }
    }
    const successCode = ['0', '200', '20000']
    if (successCode.includes(code)) {
      if (res.config.showMsg) {
        elMessage(content)
      }
      return data
    } else {
      if (code === '201') {
        elMessage(content, 'error')
        return Promise.reject(content)
      }
      // eslint-disable-next-line camelcase
      if (code === '400') {
        elMessage(content, 'error')
        return Promise.reject(content)
      }
      if (code === '401') {
        elMessage(content, 'error')
        return Promise.reject(content)
      }
      if (code === '402') {
        // token过期重新请求token
        if (!isRefreshing) {
          isRefreshing = true
          return userRefreshTokenCheck()
            .then((resp: any) => {
              const useBasicStoreIns = useBasicStore()
              useBasicStoreIns.setTokenAndInfo(resp)
              // token 刷新后将数组的方法重新执行
              requests.forEach((cb: any) => cb(resp.token))
              requests = [] // 重新请求完清空
              isRefreshing = false
              res.config.headers.Authorization = resp.token
              return service(res.config)
            })
            .catch((e) => {
              isRefreshing = false
              return Promise.reject(e)
            })
        } else {
          // 返回未执行 resolve 的 Promise
          return new Promise((resolve) => {
            // 用函数形式将 resolve 存入，等待刷新后再执行
            requests.push((token) => {
              res.headers.Authorization = token
              resolve(service(res.config))
            })
          })
        }
      }
      if (code === '403' || code === '404') {
        elMessage('即将跳转到统一登录页面', 'error')
        setTimeout(() => {
          window.open('http://gys.zcglsz.com:8095/', '_self')
        }, 1000)
      }
      // @ts-ignore
      if (!res.reqIsNotTipErrorMsg) {
        ElMessage.error({
          message: content || '系统错误',
          duration: 2 * 1000
        })
      }
      return Promise.reject(content)
    }
  },
  //响应报错
  (err) => {
    //取消请求
    useBasicStore().remotePromiseArrByReqUrl(tempReqUrlSave)
    if (loadingInstance) {
      loadingInstance && loadingInstance.close()
    }
    ElMessage.error({
      message: err,
      duration: 2 * 1000
    })
    return Promise.reject(err)
  }
)
//导出service实例给页面调用 , config->页面的配置
export default function axiosReq(config) {
  return service({
    baseURL: import.meta.env.VITE_APP_BASE_URL,
    timeout: 1000 * 30,
    ...config
  })
}
